package qlc.javafx;

import javafx.application.Application;
import javafx.geometry.HPos;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.stage.Stage;

public class ExpressionFX extends Application {
    private TextField expression = new TextField();
    private TextField result = new TextField();
    private Button calculateOrReset = new Button("Calculate");

    @Override
    public void start(Stage primaryStage) throws Exception {
        BorderPane pane = new BorderPane(getGridPane());
        pane.setBottom(getKeyBoard());
        BorderPane.setAlignment(pane.getBottom(), Pos.CENTER);

        Scene scene = new Scene(pane, 350, 300);
        primaryStage.setTitle("Simple Calculator");
        primaryStage.setScene(scene);
        primaryStage.setResizable(false);
        primaryStage.show();
    }

    public GridPane getGridPane() {
        GridPane pane = new GridPane();
        pane.setAlignment(Pos.CENTER);
        pane.setStyle("-fx-hgap: 5; -fx-vgap: 5; ");

        pane.addRow(0, new Label("Expression:"),expression);
        pane.addRow(1, new Label("Result:"),result);
        pane.add(calculateOrReset, 1, 2);

        calculateOrReset.setPrefWidth("Calculate".length()*10);
        calculateOrReset.setOnAction(e->calculate());

        GridPane.setHalignment(calculateOrReset, HPos.RIGHT);
        expression.setAlignment(Pos.BOTTOM_RIGHT);
        result.setAlignment(Pos.BOTTOM_RIGHT);
        result.setEditable(false);

        return pane;
    }

    public GridPane getKeyBoard() {
        GridPane pane = new GridPane();
        pane.setAlignment(Pos.CENTER);
        pane.setHgap(40);

        Label[] label = new Label[16];

        for (int i = 0; i < 10; i++) {
            label[i] = new Label(""+i);
        }
        label[10] = new Label("+");
        label[11] = new Label("-");
        label[12] = new Label("*");
        label[13] = new Label("/");
        label[14] = new Label("00");
        label[15] = new Label(".");

        for (Label l : label) {
            l.setFont(Font.font("宋体", FontWeight.BOLD, 24));
        }

        int index = 1;
        for (int i = 0; i < 3; i++)
            for (int j = 0; j < 3; j++)
                pane.add(label[index++], j, i);
        pane.addColumn(3, label[10],label[11],label[12],label[13]);
        pane.add(label[14], 0, 3);
        pane.add(label[0], 1, 3);
        pane.add(label[15], 2, 3);

        for (Label l : label) {
            GridPane.setHalignment(l, HPos.CENTER);
        }

        label[0].setOnMouseClicked(e->calculate("0"));
        label[1].setOnMouseClicked(e->calculate("1"));
        label[2].setOnMouseClicked(e->calculate("2"));
        label[3].setOnMouseClicked(e->calculate("3"));
        label[4].setOnMouseClicked(e->calculate("4"));
        label[5].setOnMouseClicked(e->calculate("5"));
        label[6].setOnMouseClicked(e->calculate("6"));
        label[7].setOnMouseClicked(e->calculate("7"));
        label[8].setOnMouseClicked(e->calculate("8"));
        label[9].setOnMouseClicked(e->calculate("9"));
        label[10].setOnMouseClicked(e->calculate("+"));
        label[11].setOnMouseClicked(e->calculate("-"));
        label[12].setOnMouseClicked(e->calculate("*"));
        label[13].setOnMouseClicked(e->calculate("/"));
        label[14].setOnMouseClicked(e->calculate("00"));
        label[15].setOnMouseClicked(e->calculate("."));
        return pane;
    }
    private void calculate(String tag) {
        expression.setText(expression.getText()+tag);
    }
    private void calculate() {
        try {
            if(calculateOrReset.getText().equals("Calculate")) {
                double result = CalculateExpression.operateExpression(expression.getText());

                if(result == Double.MIN_NORMAL)
                    this.result.setText("Invalid Expression");
                else {
                    String string = String.valueOf(result);
                    if(string.charAt(string.length()-1) == '0')
                        this.result.setText(String.valueOf((int)result));
                    else
                        this.result.setText(String.valueOf(result));
                }
                calculateOrReset.setText("Reset");
            }else {
                expression.setText("");
                result.setText("");
                calculateOrReset.setText("Calculate");
            }
        }catch (RuntimeException e) {
            expression.setText("");
            result.setText("");
        }
    }
    public static void main(String[] args) {
        launch(args);
    }
}

